package com.hk.hkvedio.monitor;

import com.alibaba.fastjson.JSONObject;
import com.hk.hkvedio.config.MyWebSocket;
import com.hk.hkvedio.utils.HCNetSDK;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liu
 */
@Component
public class HkVideoMonitor implements HCNetSDK.FMSGCallBack {

    @Autowired
    MyWebSocket myWebSocket;

    private static HkVideoMonitor hkVideoMonitor;

    @PostConstruct
    public void init() {
        hkVideoMonitor = this;
        hkVideoMonitor.myWebSocket = this.myWebSocket;

    }


    @Override
    public void invoke(NativeLong lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, HCNetSDK.RECV_ALARM pAlarmInfo, int dwBufLen, Pointer pUser) {
        System.out.println("正在监听......");
        String sAlarmType = new String();
        String[] newRow = new String[4];
        String[] sIP = new String[2];
        //lCommand是传的报警类型
        switch (lCommand.intValue()) {
            case HCNetSDK.COMM_ALARM_V40:
                HCNetSDK.NET_DVR_ALARMINFO_V40 struAlarmInfoV40 = new HCNetSDK.NET_DVR_ALARMINFO_V40();
                struAlarmInfoV40.write();
                Pointer pInfoV40 = struAlarmInfoV40.getPointer();
                pInfoV40.write(0, pAlarmInfo.RecvBuffer, 0, struAlarmInfoV40.size());
                struAlarmInfoV40.read();

                switch (struAlarmInfoV40.struAlarmFixedHeader.dwAlarmType) {
                    case 0:
                        struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.setType(HCNetSDK.struIOAlarm.class);
                        struAlarmInfoV40.read();
                        sAlarmType = sAlarmType + new String("：信号量报警") + "，" + "报警输入口：" + struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.struioAlarm.dwAlarmInputNo;
                        break;
                    case 1:
                        sAlarmType = sAlarmType + new String("：硬盘满");
                        break;
                    case 2:
                        sAlarmType = sAlarmType + new String("：信号丢失");
                        break;
                    case 3:
                        struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.setType(HCNetSDK.struAlarmChannel.class);
                        struAlarmInfoV40.read();
                        int iChanNum = struAlarmInfoV40.struAlarmFixedHeader.ustruAlarm.sstrualarmChannel.dwAlarmChanNum;
                        sAlarmType = sAlarmType + new String("：移动侦测") + "，" + "报警通道个数：" + iChanNum + "，" + "报警通道号：";

                        for (int i = 0; i < iChanNum; i++) {
                            byte[] byChannel = struAlarmInfoV40.pAlarmData.getByteArray(i * 4, 4);

                            int iChanneNo = 0;
                            for (int j = 0; j < 4; j++) {
                                int ioffset = j * 8;
                                int iByte = byChannel[j] & 0xff;
                                iChanneNo = iChanneNo + (iByte << ioffset);
                            }

                            sAlarmType = sAlarmType + "+ch[" + iChanneNo + "]";
                        }

                        break;
                    case 4:
                        sAlarmType = sAlarmType + new String("：硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = sAlarmType + new String("：读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = sAlarmType + new String("：遮挡报警");
                        break;
                    case 7:
                        sAlarmType = sAlarmType + new String("：制式不匹配");
                        break;
                    case 8:
                        sAlarmType = sAlarmType + new String("：非法访问");
                        break;
                }

//                newRow[0] = dateFormat.format(today);
//                //报警类型
//                newRow[1] = sAlarmType;
//                //报警设备IP地址
//                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
//                newRow[2] = sIP[0];
                break;
            //9000报警信息主动上传
            case HCNetSDK.COMM_ALARM_V30:
                HCNetSDK.NET_DVR_ALARMINFO_V30 strAlarmInfoV30 = new HCNetSDK.NET_DVR_ALARMINFO_V30();
                strAlarmInfoV30.write();
                Pointer pInfoV30 = strAlarmInfoV30.getPointer();
                pInfoV30.write(0, pAlarmInfo.RecvBuffer, 0, strAlarmInfoV30.size());
                strAlarmInfoV30.read();
                switch (strAlarmInfoV30.dwAlarmType) {
                    case 0:
                        sAlarmType = new String("信号量报警");
                        break;
                    case 1:
                        sAlarmType = new String("硬盘满");
                        break;
                    case 2:
                        sAlarmType = new String("信号丢失");
                        break;
                    case 3:
                        sAlarmType = new String("移动侦测");

                        break;
                    case 4:
                        sAlarmType = new String("硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = new String("读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = new String("遮挡报警");
                        break;
                    case 7:
                        sAlarmType = new String("制式不匹配");
                        break;
                    case 8:
                        sAlarmType = new String("非法访问");
                        break;
                }

                newRow[0] = lCommand.toString();
                newRow[1] = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                //报警类型
                newRow[2] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[3] = sIP[0];


                Map<String, String> m = new HashMap<>(18);
                m.put("id", lCommand.toString());
                m.put("time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                m.put("type", sAlarmType);
                m.put("ip", sIP[0]);
                hkVideoMonitor.myWebSocket.baojing(JSONObject.toJSONString(m));
                break;
            //8000报警信息主动上传
            case HCNetSDK.COMM_ALARM:
                System.out.println("8000报警");
                HCNetSDK.NET_DVR_ALARMINFO strAlarmInfo = new HCNetSDK.NET_DVR_ALARMINFO();
                strAlarmInfo.write();
                Pointer pInfo = strAlarmInfo.getPointer();
                pInfo.write(0, pAlarmInfo.RecvBuffer, 0, strAlarmInfo.size());
                strAlarmInfo.read();

                switch (strAlarmInfo.dwAlarmType) {
                    case 0:
                        sAlarmType = new String("信号量报警");
                        break;
                    case 1:
                        sAlarmType = new String("硬盘满");
                        break;
                    case 2:
                        sAlarmType = new String("信号丢失");
                        break;
                    case 3:
                        sAlarmType = new String("移动侦测");
                        break;
                    case 4:
                        sAlarmType = new String("硬盘未格式化");
                        break;
                    case 5:
                        sAlarmType = new String("读写硬盘出错");
                        break;
                    case 6:
                        sAlarmType = new String("遮挡报警");
                        break;
                    case 7:
                        sAlarmType = new String("制式不匹配");
                        break;
                    case 8:
                        sAlarmType = new String("非法访问");
                        break;
                }

                newRow[0] = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                break;

            //ATM DVR transaction information
            case HCNetSDK.COMM_TRADEINFO:
                //处理交易信息报警
                break;

            //IPC接入配置改变报警
            case HCNetSDK.COMM_IPCCFG:
                // 处理IPC报警
                break;
            //smart报警
            case HCNetSDK.COMM_ALARM_RULE:


                System.out.println("smart报警");
                strAlarmInfo = new HCNetSDK.NET_DVR_ALARMINFO();
                strAlarmInfo.write();
                pInfo = strAlarmInfo.getPointer();
                pInfo.write(0, pAlarmInfo.RecvBuffer, 0, strAlarmInfo.size());
                strAlarmInfo.read();
                System.out.println(strAlarmInfo.dwAlarmType);
//

                switch (strAlarmInfo.dwAlarmType) {
                    case 352:
                        sAlarmType = new String("越界报警");
                        break;
                    default:
                        break;
                }
                newRow[0] = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));
                //报警类型
                newRow[1] = sAlarmType;
                //报警设备IP地址
                sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                newRow[2] = sIP[0];
                Map<String, String> mm = new HashMap<>(18);
                mm.put("id", lCommand.toString());
                mm.put("time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                mm.put("type", sAlarmType);
                mm.put("ip", sIP[0]);
                hkVideoMonitor.myWebSocket.baojing(JSONObject.toJSONString(mm));
                break;

            default:
                System.out.println("未知报警类型");
                break;
        }
        System.out.println(JSONObject.toJSONString(newRow));


    }
}
